import datetime
from google.appengine.ext import db
from google.appengine.api import memcache
from google.appengine.api import users



def recentchange(fun):
  '''
  Decorate the put method.
  Catch artical & comment Change
  Present the global logic.
  '''
  def cordinator(self, *args, **kwargs):
    if self.__class__.__name__ == 'Articals':
      return articalschange(self, *args, **kwargs)
    elif self.__class__.__name__ == 'Comments':
      return commentschange(self, *args, **kwargs)

  def articalschange(self, *args, **kwargs):
    if fun.__name__ == 'init_put':
      keyname = Archivelist.keygen(self.postdate.year,self.postdate.month)
      monthlist = Archivelist.get_or_insert(key_name = keyname)
      monthlist.month = datetime.date(self.postdate.year,self.postdate.month,1)
      monthlist.month_num += 1
      monthlist.put()
      self.month_list = monthlist
      memcache.set_multi(
                         {
                          "time_of_new_artical_add":self.postdate,
                          "update_rss":True
                          }
                         )
      BasicSet.set_articalchanged(True)
    super(self.__class__,self).put()
    return fun(self,*args,**kwargs)

  def commentschange(self, *args, **kwargs):
    if fun.__name__ =='init_put':
      instant_articals = args[0]
      self.artical = instant_articals
      instant_articals.num_comments += 1
      instant_articals.put()
    super(self.__class__,self).put()
    return fun(self,*args,**kwargs)

  return cordinator

class BasicSet(db.Model):
  listcache = db.BlobProperty()
  articalchanged = db.BooleanProperty(default=False)
  listchanged = db.BooleanProperty(default=False)
  initial = db.BooleanProperty(default=True)

  @staticmethod
  def set_articalchanged(status):
    tmp = BasicSet.get_or_insert(key_name='basicset')
    tmp.articalchanged = status
    tmp.put()


class Archivelist(db.Model):
  """
  Item in this table is unique. that is promised by
  recentchange decorator function.

  And the Items just init or change by Articals' init_put method
  """
  user = db.UserProperty()
  month = db.DateProperty()
  month_num = db.IntegerProperty(default = 0)

  @staticmethod
  def count_this_month_artical(target_month):
    return Archivelist.get_by_key_name (key_names = target_month).this_month_artical.count()

  @staticmethod
  def keygen(year,month):
    return 'm' + str(month) + 'y' + str(year)


class Articals(db.Model):
  author = db.StringProperty()
  title = db.StringProperty()
  secondtitle = db.StringProperty()
  content = db.TextProperty()
  num_comments = db.IntegerProperty(default=0)
  postdate = db.DateTimeProperty(auto_now_add=True)
  month_list = db.ReferenceProperty(Archivelist,collection_name ='this_month_artical')

  @property
  def id(self):
    return self.key()

  @recentchange
  def put(self,*args,**kwd):
    pass

  @recentchange
  def init_put(self):
    pass

class Comments(db.Model):
  author = db.StringProperty()
  postdate = db.DateTimeProperty(auto_now_add=True)
  content = db.TextProperty()
  artical = db.ReferenceProperty(Articals,collection_name='this_artical_comment')

  @recentchange
  def put(self,*args,**kwd):
    pass

  @recentchange
  def init_put(self,instant_articals):
    pass
